package _REPLACE_THIS_STRING_WITH_REALM_TARGET_PACKAGE_;

import org.apache.commons.lang3.Validate;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import _REPLACE_THIS_STRING_WITH_ENTITY_TARGET_PACKAGE_.Permission;
import _REPLACE_THIS_STRING_WITH_ENTITY_TARGET_PACKAGE_.Role;
import _REPLACE_THIS_STRING_WITH_ENTITY_TARGET_PACKAGE_.User;
import _REPLACE_THIS_STRING_WITH_REPOSITORY_TARGET_PACKAGE_.UserRepository;

@Component
public class PersistenceRealm extends AuthorizingRealm {
	
	@Autowired
	private UserRepository userRepository;

	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
		Long userId = (Long) principals.fromRealm(getName()).iterator().next();
		User user = userRepository.findUserById(userId);
		Validate.notNull(user); //TODO: Create validation class that returns boolean on notNull?
		if (user != null) {
			SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
			for (Role role : user.getRoles()) {
				info.addRole(role.getName());
				for (Permission permission : role.getPermissions()) {
					info.addStringPermission(permission.getString());
				}				
			}
			return info;
		}
		return null;
	}

	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authcToken) throws AuthenticationException {
		UsernamePasswordToken token = (UsernamePasswordToken) authcToken;
		User user = userRepository.findUserByUsername(token.getUsername());
		if (user != null) {
			return new SimpleAuthenticationInfo(user.getId(), user.getPassword(), getName());
		} else {
			return null;
		}		
	}
}
